package com.think.admin.util;

import cn.hutool.json.JSONObject;
import com.think.common.utils.SysUtils;
import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.xssf.usermodel.*;

import javax.servlet.http.HttpServletResponse;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.List;

/**
 * <b>Excel工具类</b>
 * @author: CaiWenYi
 * @date: 2019年10月22日 下午1:43:21
 */
public class SysExcelUtils{

	// 2007 版本以上 最大支持1048576行,文件尾缀.xlsx
	public  final static String  EXCEL_FILE_2007 = "2007";

	/**
	 * <p>
	 * 导出带有头部标题行的Excel <br>(支持上一总表头，下无限子表头)
	 * 时间格式默认：yyyy-MM-dd hh:mm:ss <br>
	 * </p>
	 * 
	 * @param mainTitle 主表格标题
	 * @param mainHeaders 主头部标题集合
	 * @param count 期数
	 * @param JSONObjectList 主数据集合
	 * @param version 2003 或者 2007，不传时默认生成2003版本
	 * @author: CaiWenYi
	 * @date: 2019年10月22日 下午1:43:21
	 */
	public void exportExcel(String mainTitle, String[] mainHeaders,int count, List<JSONObject> JSONObjectList, String[] jsonKey, HttpServletResponse response, String version) {
		if(SysUtils.isNotEmpty(version) && EXCEL_FILE_2007.equals(version.trim())){
			exportExcel2007(mainTitle, mainHeaders, count, JSONObjectList,jsonKey, response);
		}
	}

	/**
	 * <p>
	 * 通用Excel导出方法,利用反射机制遍历对象的所有字段，将数据写入Excel文件中 <br>
	 * 此方法生成2007版本的excel,文件名后缀：xlsx <br>
	 * </p>
	 * 
	 * @param mainTitle 表格标题名
	 * @param mainHeaders 表格头部标题集合
	 * @param count 期数
	 * @param JSONObjectList 需要显示的数据集合,集合中一定要放置符合JavaBean风格的类的对象。此方法支持的JavaBean属性的数据类型有基本数据类型及String,Date
	 */
	public void exportExcel2007(String mainTitle, String[] mainHeaders, int count,
		List<JSONObject> JSONObjectList,String[] jsonKey, HttpServletResponse response) {
		// 声明工作薄
		XSSFWorkbook workbook = new XSSFWorkbook();
		
		// 生成表格
		XSSFSheet sheet = workbook.createSheet(mainTitle);
		// 设置表格默认列宽度为15个字节
		sheet.setDefaultColumnWidth(20);
		//导入表格数据
		this.exportXlsxExcelContents(workbook,sheet,mainHeaders,JSONObjectList, jsonKey,count);
		//调整列宽，变成自适应列宽
		int i;
		for (i = 0; i < mainHeaders.length; i++) {
			sheet.autoSizeColumn((short)i); //调整宽度
			sheet.setColumnWidth(i, sheet.getColumnWidth(i) * 15 / 10);
		}

		for (int j = 0;j < count;j++){
			sheet.autoSizeColumn((short)i); //调整宽度
			sheet.setColumnWidth(i, sheet.getColumnWidth(i) * 15 / 10);
			i++;
		}
		
		try {
			// 写入文件中
	        OutputStream os = response.getOutputStream();
			
			response.reset();// 清空输出流
            response.setHeader("Access-Control-Allow-Origin","*");
			response.setHeader("Content-Disposition", "attachment;filename=" +URLEncoder.encode(mainTitle + ".xlsx", "UTF-8")); // 设定输出文件头,该方法有两个参数，分别表示应答头的名字和值。XSSF:xlsx    HSSF:xls  中文要用encode处理一下
			response.setContentType("application/msexcel");
			response.setContentType("text/html; charset=UTF-8"); //设置编码字符
			
            workbook.write(os);
    		os.flush();
    		os.close();
    		workbook.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} 
	}

	/**
	 * 生成Header样式,并且生成内容
	 * @author: CaiWenYi
	 * @date: 2019年10月29日 下午1:38:29
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public void exportXlsxExcelContents(XSSFWorkbook workbook,XSSFSheet sheet,String[] Headers,
		List<JSONObject> JSONObjectList,String[] jsonKey ,int count) {
		//生成Header样式
		XSSFCellStyle headerStyle = this.getXlsxHeaderStyle(workbook);
		//生成Cell样式
		XSSFCellStyle cellStyle = this.getXlsxCellStyle(workbook);
        //生成Cell样式
        XSSFCellStyle cellRedStyle = this.getXlsxCellRedStyle(workbook);

		//开始创建内容的行数
		XSSFRow row = sheet.createRow(0);
		XSSFCell cellHeader;
		int startRow = 0;
		
		//产生表格标题行
		int i;
		for (i = 0; i < Headers.length; i++) {
			cellHeader = row.createCell(i);
			cellHeader.setCellStyle(headerStyle);
			cellHeader.setCellValue(new XSSFRichTextString(Headers[i]));
		}

		for (int j = 0;j < count;j++){
			cellHeader = row.createCell(i);
			cellHeader.setCellStyle(headerStyle);
			cellHeader.setCellValue("第"+(j+1)+"期");
            i++;
		}

		// 遍历集合数据，产生数据行
		if(SysUtils.isNotEmpty(JSONObjectList)){
			int index = startRow;
			XSSFCell cell;
			for (JSONObject jsonObject : JSONObjectList) {
				index++;
				int m = 0;
				row = sheet.createRow(index);
				for(String key : jsonKey){
					cell = row.createCell(m);
					cell.setCellStyle(cellStyle);
                    getcell(cell,jsonObject.get(key));
                    if(SysUtils.isNotNull(jsonObject.get(key))){
                        if(-1 != jsonObject.get(key).toString().indexOf("未交")){
                            cell.setCellStyle(cellRedStyle);
                        }
                    }
					m++;
				}

				for (int n = 1;n<count+1;n++){
					cell = row.createCell(m);
					cell.setCellStyle(cellStyle);
                    getcell(cell,jsonObject.get("amountExplain"+n));
                    if(SysUtils.isNotNull(jsonObject.get("amountExplain"+n))){
                        if(-1 != jsonObject.get("amountExplain"+n).toString().indexOf("未交")){
                            cell.setCellStyle(cellRedStyle);
                        }
                    }
					m++;
				}
			}
		}
	}

    public XSSFCell getcell(XSSFCell cell,Object object) {
	    if(SysUtils.isEmpty(object)){
            cell.setCellValue("");
	        return cell;
        }
        // 判断值的类型后进行强制类型转换
        String textValue = null;
        if (object instanceof Integer) {
            cell.setCellValue((Integer) object);
        } else if (object instanceof Float) {
            textValue = String.valueOf((Float) object);
            cell.setCellValue(textValue);
        } else if (object instanceof Double) {
            textValue = String.valueOf((Double) object);
            cell.setCellValue(textValue);
        } else if (object instanceof Long) {
            cell.setCellValue((Long) object);
        }else if (object instanceof LocalDateTime) {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            textValue = sdf.format((LocalDateTime) object);
            cell.setCellValue(textValue);
        } else {
            // 其它数据类型都当作字符串简单处理
            textValue = object.toString();
            cell.setCellValue(textValue);
        }
        return cell;
    }
	
	/**
	 * 生成Header样式
	 * @author: CaiWenYi
	 * @date: 2019年10月29日 下午1:38:29
	 */
	public XSSFCellStyle getXlsxHeaderStyle(XSSFWorkbook workbook) {
		XSSFCellStyle headerStyle = workbook.createCellStyle();
		// 设置这些样式
		headerStyle.setFillForegroundColor(IndexedColors.GREY_40_PERCENT.index);
		headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
		headerStyle.setBorderBottom(BorderStyle.THIN);
		headerStyle.setBorderLeft(BorderStyle.THIN);
		headerStyle.setBorderRight(BorderStyle.THIN);
		headerStyle.setBorderTop(BorderStyle.THIN);
		headerStyle.setAlignment(HorizontalAlignment.CENTER);
		headerStyle.setVerticalAlignment(headerStyle.getVerticalAlignmentEnum().CENTER);
		// 生成一个字体
		XSSFFont headerFont = workbook.createFont();
		headerFont.setBold(true);
		headerFont.setFontName("宋体"); 
		headerFont.setColor(IndexedColors.BLACK.index);
		// 把字体应用到当前的样式
		headerStyle.setFont(headerFont);
		return headerStyle;
	}
	
	/**
	 * 生成Cell样式
	 * @author: CaiWenYi
	 * @date: 2019年10月29日 下午1:43:12
	 */
	private XSSFCellStyle getXlsxCellStyle(XSSFWorkbook workbook) {
		XSSFCellStyle cellStyle = workbook.createCellStyle();
		cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
		cellStyle.setBorderBottom(BorderStyle.THIN);
		cellStyle.setBorderLeft(BorderStyle.THIN);
		cellStyle.setBorderRight(BorderStyle.THIN);
		cellStyle.setBorderTop(BorderStyle.THIN);
		cellStyle.setAlignment(HorizontalAlignment.CENTER);
		cellStyle.setVerticalAlignment(cellStyle.getVerticalAlignmentEnum().CENTER);
		return cellStyle;
	}

    /**
     * 生成Cell样式
     * @author: CaiWenYi
     * @date: 2019年10月29日 下午1:43:12
     */
    private XSSFCellStyle getXlsxCellRedStyle(XSSFWorkbook workbook) {
		XSSFCellStyle cellStyle = workbook.createCellStyle();
		cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
		cellStyle.setBorderBottom(BorderStyle.THIN);
		cellStyle.setBorderLeft(BorderStyle.THIN);
		cellStyle.setBorderRight(BorderStyle.THIN);
		cellStyle.setBorderTop(BorderStyle.THIN);
		cellStyle.setAlignment(HorizontalAlignment.CENTER);
		cellStyle.setVerticalAlignment(cellStyle.getVerticalAlignmentEnum().CENTER);
        // 生成另一个字体
        XSSFFont cellFont = workbook.createFont();
        cellFont.setColor(IndexedColors.RED.index);
		cellFont.setBold(true);
        // 把字体应用到当前的样式
        cellStyle.setFont(cellFont);
        return cellStyle;
    }
	
}